<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
    <style>
        body {
            display: flex;
            padding: 100px;
        }

        .container {
            position: relative;
            width: 300px;
            height: 300px;
            display: inline-block;
        }

        .container img {
            width: 100%;
            height: 100%;
        }

        .magnifier {
            width: 100px;
            background: rgba(0, 0, 0, 0.2);
            position: absolute;
            left: 0;
            top: 0;
        }

        .preview {
            width: 300px;
            position: relative;
            display: inline-block;
            overflow: hidden;
        }

        .preview img {
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
    <title>magnifier</title>
</head>

<body>
    <!-- HTML结构部分 -->
    <div class="container">
        <img src="images/small.jpg" />
        <div class="magnifier"></div>
    </div>
    <div class="preview">
        <img src="images/big.jpg" />
    </div>
    <script>
        // 获取相关的DOM元素
        const container = document.querySelector('.container');
        const magnifier = document.querySelector('.magnifier');
        const preview = document.querySelector('.preview');
        const largeImg = document.querySelector('.preview img');
        // 计算容器的宽高比 clientHeight=2,clientWidth=1,containerRatio=2
        const containerRatio = container.clientHeight / container.clientWidth;
        // 设置放大镜的高度，以保持宽高比一致 
        magnifier.style.height = magnifier.clientWidth * containerRatio + 'px';
        // 设置预览框的宽高
        preview.style.height = preview.clientWidth * containerRatio + 'px';
        // 计算预览框放大的比例
        const scale = preview.clientWidth / magnifier.clientWidth;
        // 设置放大图像的宽度和高度
        largeImg.style.width = container.clientWidth * scale + 'px';
        largeImg.style.height = container.clientHeight * scale + 'px';
        // 监听容器的鼠标移动事件
        container.addEventListener('mousemove', (e) => {
            const rect = container.getBoundingClientRect();
            let x = e.clientX - rect.left - magnifier.clientWidth / 2;
            let y = e.clientY - rect.top - magnifier.clientHeight / 2;
            // 限制放大镜的位置在容器范围内
            x = Math.max(0, Math.min(x, container.clientWidth - magnifier.clientWidth));
            y = Math.max(0, Math.min(y, container.clientHeight - magnifier.clientHeight));
            // 设置放大镜的位置和显示
            magnifier.style.left = x + 'px';
            magnifier.style.top = y + 'px';
            magnifier.style.display = 'block';
            // 设置放大图像的位置和显示
            largeImg.style.left = -x * scale + 'px';
            largeImg.style.top = -y * scale + 'px';
            largeImg.style.display = 'block';
        });
        // 监听容器的鼠标离开事件
        container.addEventListener('mouseleave', () => {
            // 隐藏放大镜和放大图像
            magnifier.style.display = 'none';
            largeImg.style.display = 'none';
        });
    </script>
</body>
</html>